package changceilingcolor003;

import java.awt.FileDialog;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import controlP5.Button;
import controlP5.CColor;
import controlP5.ControlEvent;
import controlP5.ControlP5;
import controlP5.ControlWindow;
import controlP5.Controller;
import controlP5.ListBox;
import controlP5.ListBoxItem;
import controlP5.Slider;
import controlP5.Toggle;
import processing.core.PApplet;
import processing.core.PImage;
import peasy.*;
import peasy.org.apache.commons.math.geometry.Rotation;
import toxi.geom.*;
import plethora.core.*;
import GraphTheoryTools.*;
import java.util.Timer;

import controlP5.*;

import javax.swing.JFileChooser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import peasy.PeasyCam;
import processing.core.PApplet;
import toxi.geom.Vec3D;
import toxi.physics.VerletPhysics;
import toxi.physics.VerletSpring;
import toxi.physics.behaviors.GravityBehavior;
import toxi.processing.ToxiclibsSupport;


@SuppressWarnings("serial")
public class ChangCeilingColor003 extends PApplet {

	
	//DECLARE LIBRARIES
	PeasyCam cam;
	ControlP5 controlP5;
	ControlP5 controlP5_2;
	ControlWindow ctrlWin;
	ControlWindow ctrlWin1;
	World myWorld = new World(this);
	Environment environment; 
	Grid grid;
	Ple_Terrain pTerr;
	VerletPhysics physics;
	
	
	//DirectedGraph = null;

	public String SiteFolder = loadStrings("data/SelectedSite.txt")[0];

	Configuration conf = new Configuration("data/"+SiteFolder+"/SiteConfig.xml");

	//GLOBALS
	public int width= conf.width;
	public int height= conf.height;
	public int maxZ= conf.maxZ;
	int resulotion=5;
	int COLS=width/5;
	int ROWS=height/5;
	//int pop=20;
	int pop=30;

	float pe_sep = 5.0f;
	float pe_coh = 0.5f;
	float pe_ali = 1.0f;
	float pe_sepA = 10.0f;
	float pe_sepB = 10.0f;

	
	boolean m_IsInInitPhase = true;
	boolean m_IsInEtAttractionStatePhase = false;
	boolean m_ShouldShowAttractorsRange = false;
	
	//float  attention_radios1 = 50; 
	
	
	//AreaGrid CollisionAreaGrid1 = new AreaGrid(100 +1,100 +1);
	int m_num_of_floor = 3;
	int[][][] TemperatureGrid = new int[width][height][m_num_of_floor];
	int[][][] PrevTemperatureGrid = new int[width][height][m_num_of_floor];
	
	ArrayList<Boolean>  visible_floors = new ArrayList<Boolean>(); 

	
	String sFocusedAttractionId =""; 



	boolean showTrail=false;
	boolean showDetail = false;
	boolean showPerson = true;
	boolean showBoundary=true;
	boolean showAlarm = false;
	boolean SomehowWorkFast = false;
	boolean Somemeasurement = true;
	boolean a_active = false;
	boolean activateAttractorsTemprature = false;
	boolean displayPossiblePath = false;
	boolean exportvideo = false;

	//SLIDER	
	//Vistor
	boolean Vistor= true;
	int Capacity_1=100;
	float Attract_to_art_1 = 10.0f;
	float ArtScent_1 = 0;
	float Attract_to_Social_1 = 7.0f;
	float SocialSent_1 = 7;
	float Attract_to_Collector_1 = 0;
	float CollectorSent_1 = 0;
	float Go_to_Destination_1=1;

	//Artist
	boolean Artist = true;
	int Capacity_2=40; //for siteA 
	//int Capacity_2=10; //for siteB 
	float Attract_to_art_2 = 0.6f;
	float ArtScent_2 = 0;
	float Attract_to_Social_2 =3;
	float SocialSent_2 = 2;
	float Attract_to_Collector_2 = 0.8f;
	float CollectorSent_2 = 4;
	float Go_to_Destination_2=0.5f;

	//Collector
	boolean Collector = true;
	int Capacity_3=10;//for siteA 
	//int Capacity_3=50;//for siteB 
	float Attract_to_art_3 = 10f;
	float ArtScent_3 = 4;
	float Attract_to_Social_3 = 0.2f;
	float SocialSent_3 = 0;
	float Attract_to_Collector_3 = 0.8f;
	float CollectorSent_3 = 0;
	float Go_to_Destination_3=0.5f;


	boolean bInLoadFileState =false;


	boolean PausePeople = false;
	boolean DisplayPeopleTemperator = false;
	
	int m_FloorHeight = 50;

	//ARRAYLISTS
	ArrayList<Actors> alisOrigin =new ArrayList<Actors>();
	ArrayList<Actors> alisOrigin1 =new ArrayList<Actors>();
	ArrayList<Actors> alisOrigin2 =new ArrayList<Actors>();
	ArrayList<Actors> alisOrigin3 =new ArrayList<Actors>();
	ArrayList<Actors> alisPeop =new ArrayList<Actors>();
	ArrayList<Vec3D> alisBnd1 =new ArrayList<Vec3D>();
	ArrayList<Vec3D> alisBnd2 =new ArrayList<Vec3D>();
	ArrayList<Vec3D> alisBnd3 =new ArrayList<Vec3D>();
	ArrayList<Vec3D> alisBnd4 =new ArrayList<Vec3D>();
	ArrayList<Vec3D> alisBnd5 =new ArrayList<Vec3D>();
	ArrayList<Actors> alisDst =new ArrayList<Actors>();
	HashMap<String, Attraction> AttractionDictionary= new HashMap<String, Attraction>();

	//AttractionInteractionHolder AttractionInteractionPropertiesHolder = null;

	
	//GUI global members:
	Slider x_CntRoller  =null,y_CntRoller = null,z_CntRoller  =null, range_CntRoller = null;
	Toggle isActive_CntRoller = null;
	Textlabel attractorLabel = null;

	ArrayList <Ple_Agent> boids;
	ArrayList<Actors> AllActiveActors = new ArrayList<Actors>();
	static ChangCeilingColor003 m_This = null;
//	public static ChangCeilingColor003 GetInstance()
//	{
//		if(m_This == null)
//		{
//			
//			m_This =  new ChangCeilingColor003();
//		}
//		return m_This;
//	}

	public void setup() {
//		width= 450;
//		height= 250;
//		maxZ= 200;
		SiteFolder = loadStrings("data/SelectedSite.txt")[0];
		
		
		
		boolean HidePeopleForDevelopment = false;	
		if(HidePeopleForDevelopment )
		{
			Vistor = false;
			Artist  = false;
			Collector = false;
		}
		
		
		
		

		size(900, 900, P3D);
		frameRate(20);
		initializeCamera();

		environment=new Environment(this);
		myWorld = new World(this);
		grid=new Grid(this, COLS, ROWS);
		physics = new VerletPhysics();
		sliders();
		//sliders2(); 

		myWorld.init();
		grid.init();

		Vec3D location = new Vec3D(0, 0, 0);
		pTerr = new Ple_Terrain(this, location, COLS, ROWS, resulotion, resulotion);

		CL();
		R();
		S();
		RA();	
		
		for(int i =0 ;i< m_num_of_floor;++i)
		{
			visible_floors.add(false);
		}
		
		Keyboard  k = new Keyboard(); 
		    KeyboardFocusManager.getCurrentKeyboardFocusManager() 
		    .addKeyEventDispatcher( k ); 

	}
	
	class Keyboard implements KeyEventDispatcher 
	{ 
	  Keyboard() 
	  { 
	} 

	@Override
	public boolean dispatchKeyEvent(KeyEvent arg0) {
		  int kc = arg0.getKeyCode();
		  
		  
		  
		    if ( kc == 18 )  //18 = Alt key
		    {
		      return true;
		    }
		    else {
		      return false;  //retarget key event to application
		    }
	} 
	} 

	void CL()
	{
		for (int i=0;i<alisPeop.size();i++) {
			alisPeop.remove(i);
		}
	}


	void R()
	{
		for (int i=0;i<alisPeop.size();i++) {
			alisPeop.remove(i);		
		}
		//AllActiveActors2.clear();
		//AllActiveActors.clear();


		myWorld.init();

		showPerson=true;
	}

	void S(){
		showBoundary=!showBoundary;

	}
	
	

	void RA()
	{

		///This part is unnecessary since the location delta is zero by default  
		//		for(int i =0; i<alisDst.size(); ++i)
		//		{			
		//			Actors att = alisDst.get(i);
		//			att.SetDeltaX(0);
		//			att.SetDeltaY(0);
		//			att.SetDeltaZ(0);			
		//		}
	}



	void ResumePeople()
	{
		PausePeople = false;
		m_IsInInitPhase = false;
		R();
	}

	void ShowPeopleTemp()
	{
		DisplayPeopleTemperator =  !DisplayPeopleTemperator ;
	}
	
	void AttractorsTemprature()
	{
		activateAttractorsTemprature = !activateAttractorsTemprature;
	}
	
	void DisplayPossiblePath()
	{	
		displayPossiblePath = !displayPossiblePath;
	}
	
	void CalculatePossiblePath()
	{
		myWorld.CheckPossiblePath();
	//	displayPossiblePath = !displayPossiblePath;
	}
	
	void RedeployPepole()
	{
		R();
	
	}
	
	public void draw() {
		background(0);
		smooth();
		
	
		//for (int i=0;i<AllActiveActors.size();i++) {
		//AllActiveActors.get(i).Draw();
		//}
		
		
		
		
		for (int i=0;i<AllActiveActors.size();i++) {
			AllActiveActors.get(i).Draw();
		}
		environment.run();

		if (showPerson==true){
			myWorld.run();
		}

		if(!SomehowWorkFast)
		{
		grid.run();
		grid.clear();
		}
		if (exportvideo==true && frameCount<3000){
		if (exportvideo==true){
			saveFrame("Video/frame"+frameCount+".png");
			println(frameCount);
		}


		//g.draw();

		//video
		if (frameCount%200==0){
		//saveFrame("Video/frame"+frameCount+".tiff");
		}
		}
	}



	void initializeCamera() {
		//cam = new PeasyCam(this, 261.94977, 193.22641, 30.904861, 550);
		cam = new PeasyCam(this, 250, 150, 25, 480);
		setCam();

	}
	//
	void setCam() {
		cam.setMinimumDistance(.001);
		cam.setMaximumDistance(10000);
		//cam.setRotations(1.4720584, 0.76990885, -3.0659537);
		cam.setRotations(0, 0, 0);
	}
	//
	void getCamSettings() {  
		float[] cLook = cam.getLookAt();
		float[] cRot = cam.getRotations();
		println( cLook[0] + ", " +  cLook[1]+ ", " +  cLook[2]);
		println( cRot[0] + ", " +  cRot[1]+ ", " +  cRot[2]);
	}
	
	void cam01() {
		//main entrance view
		  smooth();
		  //cam = new PeasyCam(this, 192.89276, 114.86514, 12.856212, 500);
		  //cam.setRotations(-0.901282, 0.39011994, -0.40040308);
		  //cam = new PeasyCam(this, 243.65347, 75.72699, -4.8980913, 588.4501600081137);
		  //cam.setRotations(-0.89246595, 0.60679114, -0.48337832);
		  
		  //cam = new PeasyCam(this, 200.39223, 119.0602, -43.31067, 588.4501600081137);
		  //cam.setRotations(-1.0977335, 0.61431277, -0.28085336);
		  
		  
		  //cam = new PeasyCam(this,275.95795, 67.37628, -59.317665, 800);/////for output data
		  cam = new PeasyCam(this,230.73616, 105.2607, -63.32609, 588.4501600081137);
		  cam.setRotations(-1.0977335, 0.61431277, -0.28085336);
		  
		  
		}
	

		void cam02() {
		
		  smooth();
		  //cam = new PeasyCam(this,197.65942, 701.0083, 25.0,1600);  //top view for siteB
		  //cam = new PeasyCam(this,198.52278, 128.10892, 25.0,1600);  //top view for siteA
		 // cam.setRotations(-0.0, 0.0, -0.0);
		  cam = new PeasyCam(this,209.22859, 116.22542, -51.452057, 575);
		  cam.setRotations(-1.0977335, 0.61431277, -0.28085336);  
		}

		void cam03() {
		  
		  smooth();
		  //cam = new PeasyCam(this, 254.88354, 123.08456, 78.0125, 471.827189438525);
		  //cam.setRotations(-1.2579124, 1.5604136, -0.3161817);
		  
		  //street view for siteB
		  //cam = new PeasyCam(this, 114.93639, 675.94305, -12.307854, 1500);
		 // cam.setRotations(0.56033134, 0.7468479, -2.2532663);
		  cam = new PeasyCam(this, 254.70944, 142.27536, 73.16684, 471.827189438525);
		  cam.setRotations(-1.2579124, 1.5604136, -0.3161817);
		}
		void cam04() {
		 //zoom in
		  smooth();
		  //cam = new PeasyCam(this, 114.93639, 675.94305, -12.307854, 1500); //street view for siteB 
		  //cam.setRotations(0.50751746, 0.6942044, -2.2169511);
		cam = new PeasyCam(this, 218.92265, 76.62475, 12.163383, 350); 
		cam.setRotations(-1.1132057, 1.1274356, -0.3426095);
		}

		void cam05() {
			//zoom in
		  smooth();
		  cam = new PeasyCam(this,218.98888, 76.64318, 11.985743, 372);
		  cam.setRotations(-1.137022, 0.6231639, -0.25845724);
		}
		
		
		void cam06() {
			  //topview
			  smooth();
			  cam = new PeasyCam(this, 204.70232, 107.625824, 25.0, 650);
			  cam.setRotations(0, 0, 0);
			}
	


	public void keyPressed() {
		if ( key == ' ')getCamSettings();
		 //camera angles
		  if (key == '1')cam01();
		  if (key == '2')cam02();
		  if (key == '3')cam03();
          if (key == '4')cam04();
		  if (key == '5')cam05();
		  if (key == '6')cam06();
		  
		if (key=='s') {
			saveFrame("Image/frame"+frameCount+".tiff");
			println(frameCount);
		}
		
		if (key == 'e'){
			exportvideo=!exportvideo;
		}
	
		//agent's trail
		if (key == 't' && showTrail==false) {
			showTrail=true;
		}
		else if (key == 't' && showTrail==true) {
			showTrail=false;
		}

		if (key == 'd')
		{
			if( showDetail==false)
			{  
				showDetail=true;
			}
			else
			{
				showDetail=false;
			}

		}

		if (key == 'a'){
			SomehowWorkFast=!SomehowWorkFast;
		}
		
		if (key == 'b'){
			Somemeasurement=!Somemeasurement;
		}
	}

	void sliders2() {
		ControlP5 controlP5_2 = new ControlP5(this);
		ControlWindow ctrlWin1 = controlP5_2.addControlWindow("controlP5Window1", 10, 10, 300, 750);

		//Controller ms1 = controlP5_2.addButton("R", 0, 10, 400, 12, 12);
		//ms1.setWindow(ctrlWin1);
		//Controller ms2 =controlP5_2.addTextlabel("Label15","Reset",26,403);
		//ms2.setWindow(ctrlWin1);

		//Controller ms3 = controlP5_2.addButton("CL", 0, 10, 420, 12, 12);
		//ms3.setWindow(ctrlWin1);
		//Controller ms4 =controlP5_2.addTextlabel("Label16","Clear",26,423);
		//ms4.setWindow(ctrlWin1);

		//Controller ms5 = controlP5_2.addButton("S", 0, 10,440, 12, 12);
		//ms5.setWindow(ctrlWin1);	
		//Controller ms333 =controlP5_2.addTextlabel("Label17","Surrounding",26,443);
		//ms333.setWindow(ctrlWin1);

		//Controller ms6 = controlP5_2.addButton("RA", 0, 10,460, 12, 12);
		//ms6.setWindow(ctrlWin1);	
		//Controller ms7 =controlP5_2.addTextlabel("Label18","ResetAttractionPostion",26,463);
		//ms7.setWindow(ctrlWin1);

		//Controller ms8 = controlP5_2.addButton("ResumePeople", 0, 10,480, 12, 12);
		//ms8.setWindow(ctrlWin1);
		//Add every attraction that was read from the file
		int AttractionGUI_x = 10;
		int AttractionGUI_y = 10;
		for(int i=0; i < alisDst.size(); i++)
		{

			if(i>3)
			{
				AttractionGUI_y = (i-4)*120+10;
				AttractionGUI_x = 200;
			}
			else
			{
				AttractionGUI_y = i*120+10;
				AttractionGUI_x = 10;
			}
			Attraction att =  (Attraction) alisDst.get(i);
			AddAtrractionToGUI2(ctrlWin1,controlP5_2 , att, AttractionGUI_x,AttractionGUI_y);
		}


	}

	private void AddAtrractionToGUI2(ControlWindow ctrlWin,ControlP5 _controlP5, Attraction attraction,int x,int y)
	{
		//Controller ms0 = _controlP5.addTextlabel(attraction.GetId()+"Label", attraction.GetDescription(),x+12,y+14 );
		Controller ms0 = _controlP5.addTextlabel(attraction.GetId()+"Label", attraction.GetDescription(),x+12,y+2);
		ms0.setWindow(ctrlWin);

		Controller ms1 = _controlP5.addToggle(attraction.GetId() + "_",attraction.m_active, x, y, 10, 10); 
		ms1.setWindow(ctrlWin);

		//stroke(255,255,255);//////////////////////////////////////////////////////////////
		//text(attraction.GetArea(),x,y+22);

		//Controller ms2 = _controlP5.addNumberbox("",attraction.GetArea(), x, y + 30, 10, 10);
		//ms2.setWindow(ctrlWin);/////////////////////////////////////

	}
	void CheckPossibleConnections()
	{
		m_IsInEtAttractionStatePhase = !m_IsInEtAttractionStatePhase;	
	}

	void  ShowAttractorsRange()
	{
		m_ShouldShowAttractorsRange = !m_ShouldShowAttractorsRange;
	}

	void sliders() {
			
		ControlP5 controlP5 = new ControlP5(this);
		ControlWindow ctrlWin = controlP5.addControlWindow("controlP5Window", 10, 10, 600, 750);		
		/////////////////////////addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theWidth, theHeight);
	
		
		
		
		
		
		
		//Vistor
		controlP5.addToggle("Vistor", true, 10,10, 10, 10).setWindow(ctrlWin);
		controlP5.addTextlabel("Label11","Vistor",22,12).setWindow(ctrlWin);
		controlP5.addSlider("Go to Destination_1", 0, 2, Go_to_Destination_1, 10, 24, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Capacity_1", 0, 100,Capacity_1, 200,24, 70, 10).setWindow(ctrlWin);
		controlP5.addTextlabel("Label14","Desire",10,48).setWindow(ctrlWin);
		controlP5.addTextlabel("Label144","Attrat",200,48).setWindow(ctrlWin);
		controlP5.addSlider("Attract to_art_1", 0, 10, Attract_to_art_1, 10, 60, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("ArtScent_1", 0, 10, ArtScent_1, 200, 60, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Attract to_Social_1", 0, 10, Attract_to_Social_1, 10, 80, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("SocialSent_1", 0, 10, SocialSent_1, 200, 80, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Attract to_Collector_1", 0, 10, Attract_to_Collector_1, 10, 100, 70, 10).setWindow(ctrlWin); 		
		controlP5.addSlider("CollectorSent_1", 0, 10, CollectorSent_1, 200, 100, 70, 10).setWindow(ctrlWin); 

		//Artist
		controlP5.addToggle("Artist", true, 10, 130, 10, 10).setWindow(ctrlWin);

		controlP5.addTextlabel("Label12","Artist",22,132).setWindow(ctrlWin);
		controlP5.addSlider("Go to Destination_2", 0, 2, Go_to_Destination_2, 10, 144, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Capacity_2", 0, 100, Capacity_2, 200, 144, 70, 10).setWindow(ctrlWin);
		
		controlP5.addTextlabel("Label1144","Desire",10,168).setWindow(ctrlWin);
		controlP5.addTextlabel("Label1444","Attrat",200,168).setWindow(ctrlWin);
		controlP5.addSlider("Attract to_art_2", 0, 10, Attract_to_art_2, 10, 180, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("ArtScent_2", 0, 10, ArtScent_2, 200, 180, 70, 10).setWindow(ctrlWin);

		controlP5.addSlider("Attract to_Social_2", 0, 10, Attract_to_Social_2, 10, 200, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("SocialSent_2", 0, 10, SocialSent_2, 200, 200, 70, 10).setWindow(ctrlWin);
			
		controlP5.addSlider("Attract to_Collector_2", 0, 10, Attract_to_Collector_2, 10, 220, 70, 10).setWindow(ctrlWin);

		controlP5.addSlider("CollectorSent_2", 0, 10, CollectorSent_2, 200, 220, 70, 10).setWindow(ctrlWin); 
		
		//Collector
		controlP5.addToggle("Collector", true, 10, 250, 10, 10).setWindow(ctrlWin);
		controlP5.addTextlabel("Label13","Collector",22,252).setWindow(ctrlWin);
		controlP5.addSlider("Go to Destination_3", 0, 2, Go_to_Destination_3, 10,264, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Capacity_3", 0, 100, Capacity_3,200, 264, 70, 10).setWindow(ctrlWin);
		controlP5.addTextlabel("Label1114444","Desire",10,288).setWindow(ctrlWin);
		
		controlP5.addTextlabel("Label1111144","Attrat",200,288).setWindow(ctrlWin);
		
		controlP5.addSlider("Attract to_art_3", 0, 10, Attract_to_art_3, 10, 300, 70, 10).setWindow(ctrlWin);

		controlP5.addSlider("ArtScent_3", 0, 10, ArtScent_3, 200, 300, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("Attract to_Social_3", 0, 10, Attract_to_Social_3, 10, 320, 70, 10).setWindow(ctrlWin);
		
		controlP5.addSlider("SocialSent_3", 0, 10, SocialSent_3, 200, 320, 70, 10).setWindow(ctrlWin);

		controlP5.addSlider("Attract to_Collector_3", 0, 10, Attract_to_Collector_3, 10, 340, 70, 10).setWindow(ctrlWin);
		controlP5.addSlider("CollectorSent_3", 0, 10, CollectorSent_3, 200, 340, 70, 10).setWindow(ctrlWin);
		
		controlP5.addButton("R", 0, 10, 400, 12, 12).setWindow(ctrlWin);
		controlP5.addTextlabel("Label15","Reset",26,403).setWindow(ctrlWin);
		controlP5.addButton("CL", 0, 10, 420, 12, 12).setWindow(ctrlWin);
		controlP5.addTextlabel("Label16","Clear",26,423).setWindow(ctrlWin);
		controlP5.addButton("S", 0, 10,440, 12, 12).setWindow(ctrlWin);
		controlP5.addTextlabel("Label17","Surrounding",26,443).setWindow(ctrlWin);
		controlP5.addButton("RA", 0, 10,460, 12, 12).setWindow(ctrlWin);


		controlP5.addButton("ResumePeople", 0, 10,480, 12, 12).setWindow(ctrlWin);
		controlP5.addButton("ShowPeopleTemp", DisplayPeopleTemperator?1:0, 10,500, 40, 12).setWindow(ctrlWin);
		controlP5.addButton("AttractorsTemprature", activateAttractorsTemprature?1:0, 10,520, 100, 12).setWindow(ctrlWin);
		controlP5.addButton("CalculatePossiblePath",0,10,540, 100, 12).setWindow(ctrlWin);		
		controlP5.addButton("DisplayPossiblePath", displayPossiblePath?1:0, 10,560, 100, 12).setWindow(ctrlWin);
		controlP5.addButton("RedeployPepole", 0, 10,580, 100, 12).setWindow(ctrlWin);
		
		controlP5.addToggle("SaveAttractionStateWrapper", false, 10,600, 100, 12).setWindow(ctrlWin);
		
		controlP5.addButton("CheckPossibleConnections", m_IsInEtAttractionStatePhase?1:0, 10,640, 100, 12).setWindow(ctrlWin);
		
		
		controlP5.addButton("ShowAttractorsRange", m_ShouldShowAttractorsRange?1:0, 10,660, 100, 12).setWindow(ctrlWin);
		
		
		
		controlP5.addToggle("LoadAttractionStateWrapper", false, 10,680, 100, 12).setWindow(ctrlWin);
		
		for(int i =0 ;i< m_num_of_floor;++i)
		{
			controlP5.addToggle("VisibleFloor_"+i, false, 200 +60*i,650, 40, 12).setWindow(ctrlWin);
			
			
		}
		
		

		//Add every attraction that was read from the file
		int AttractionGUI_x = 400;
		int AttractionGUI_y = 10;
		
		//controlP5.addMultiList("myList",20,20,100,12).setWindow(ctrlWin);
		
		MultiList ll = controlP5.addMultiList("myList",400,020,100,12);
		 MultiListButton b;
		ll.setWindow(ctrlWin);
		b = ll.add("programmes",1);
		//b.setWindow(ctrlWin);
		//
		
		
		
		attractorLabel = controlP5.addTextlabel("SelectedAttractor:","",400, 420);
		attractorLabel.setWindow(ctrlWin);
		
		isActive_CntRoller =controlP5.addToggle("Attraction_Activate",false, 400, 520, 10, 10);
		isActive_CntRoller.setWindow(ctrlWin);
		
		range_CntRoller =  controlP5.addSlider("Attraction_Range",0,0,0, 400, 440, 70, 10);
		range_CntRoller.setWindow(ctrlWin);
		 
		x_CntRoller = controlP5.addSlider("Attraction_X", 0,0, 0, 400, 460, 70, 10);
		
		x_CntRoller.setWindow(ctrlWin);
		y_CntRoller = controlP5.addSlider("Attraction_Y", 0,0, 0, 400,480, 70, 10);
		y_CntRoller.setWindow(ctrlWin);
		z_CntRoller = controlP5.addSlider("Attraction_Z", 0,0, 0, 400, 500, 70, 10);
		z_CntRoller.setWindow(ctrlWin);
		
		
		for(int i=0; i < alisDst.size(); i++)
		{

//			if(i>3)
//			{
//				AttractionGUI_y = (i-4)*120+10;
//				AttractionGUI_x = 600;
//			}
//			else
//			{
				AttractionGUI_y = (i%4)*120+10;
				AttractionGUI_x = 400+(int)(i/4)*200 ;
//			}
			Attraction att =  (Attraction) alisDst.get(i);
			b = ll.add("SelectAttractorToControl_"+att.GetId(),i+1);
			b.setLabel(att.GetDescription());
			
			
			b.setColorBackground(color(att.GetColorR(),att.GetColorG(),att.GetColorB())) ;
			
			
			//AddAtrractionToGUI(ctrlWin,controlP5 , att, AttractionGUI_x,AttractionGUI_y);
		}
	}

	//This part can deal with changes in the GUI(Slider, button and so on)
	public void controlEvent(ControlEvent theEvent) {

		
		
		if(theEvent.isController()) 
		{ 
			//theEvent.controller().setBroadcast(false);
			if(theEvent.controller().name().compareTo("LoadAttractionStateWrapper") ==0)
			{	
				Toggle bt = (Toggle) theEvent.controller();
				if(bt.getState())
				{
					String sSelectedFile =selectFileImplPro("LoadStateFile","", FileDialog.LOAD); 
					if(sSelectedFile!= null)
						LoadAttractionState(sSelectedFile);				
				}
				return ;				
			}
			else if(theEvent.controller().name().compareTo("SaveAttractionStateWrapper") ==0)
			{
				Toggle bt = (Toggle) theEvent.controller();
				if(bt.getState())
				{
					String sSelectedFile =selectFileImplPro("SaveStateFile","", FileDialog.SAVE); 
					if(sSelectedFile!= null)
						SaveAttractionState(sSelectedFile);				
				}
				return ;
			}
			String [] fields = PApplet.split(theEvent.controller().name(), '_');

			if(fields.length <2)
				return;

			if(fields[1].equals("Activate"))
			{
				Attraction att = AttractionDictionary.get(sFocusedAttractionId);

				if(theEvent.controller().value() == 1.0)
				{
					att.m_active= true;
				}
				else
				{
					att.m_active = false;
				}
			}
			else if(fields[0].equals("SelectAttractorToControl"))
			{
				
				SelectAttractorToControl(fields[1]);

			}
			else if(fields[0].equals("VisibleFloor"))
			{
				int nFloor = Integer.parseInt(fields[1]);
				
				visible_floors.set(nFloor,  !visible_floors.get(nFloor));
			}
			else if(fields[1].equals("Range"))
			{
				
				Actors att = AttractionDictionary.get(sFocusedAttractionId);
				att.SetAttractionRadious(theEvent.controller().value());
				
				((Attraction) att).setMassRadios((int) theEvent.controller().value());
			}
			else if(fields[1].equals("X"))
			{
				Actors att = AttractionDictionary.get(sFocusedAttractionId);
				att.SetX(theEvent.controller().value());
			}
			else if(fields[1].equals("Y"))
			{
				Actors att = AttractionDictionary.get(sFocusedAttractionId);
				att.SetY(theEvent.controller().value());
			}
			else if(fields[1].equals("Z"))
			{
				Actors att = AttractionDictionary.get(sFocusedAttractionId);
				
				att.SetFloor((int) theEvent.controller().value());
				
			}			

			//theEvent.controller().setBroadcast(true);
		}
	}
	static Vec3D ParseVec3D(String Vec3DRepresi)
	{
		String[] sVec3D = Vec3DRepresi.split(",");
		Vec3D returnValue = new Vec3D();
		returnValue.x =Float.parseFloat(sVec3D[0]) ;
		returnValue.y =Float.parseFloat(sVec3D[1]) ;
		returnValue.z =Float.parseFloat(sVec3D[2]) ;
		return returnValue; 
	}
	void LoadSaveStateFromFile(String filename)
	{
		bInLoadFileState = true;
		
		bInLoadFileState = false;
	}
	
	
	public void SelectAttractorToControl(String sAttractorId)
	{
		
		/*
		Slider x_CntRoller  =null,y_CntRoller = null,z_CntRoller  =null, range_CntRoller = null;
		Toggle isActive_CntRoller = null;
		Textlabel attractorLabel = null;
		*/
		Attraction att = AttractionDictionary.get(sAttractorId);
		attractorLabel.setValue(att.GetDescription());
		
		float x =isActive_CntRoller.position().x; float y =isActive_CntRoller.position().y;		
		
		
		isActive_CntRoller.changeValue( att.m_active?(float)1:(float)0);
		
		range_CntRoller.setBroadcast(false);
		range_CntRoller.setMin(att.m_Min_r);
		range_CntRoller.setMax(att.m_Max_r);
		range_CntRoller.setValue((float) att.AttractionRadious);
		range_CntRoller.setBroadcast(true);
		
		x_CntRoller.setBroadcast(false);
		x_CntRoller.setMin(att.m_Min_x);
		x_CntRoller.setMax(att.m_Max_x);
		x_CntRoller.setValue(att.GetLocation().x);
		x_CntRoller.setBroadcast(true);
		
		y_CntRoller.setBroadcast(false);
		y_CntRoller.setMin(att.m_Min_y);
		y_CntRoller.setMax(att.m_Max_y);
		y_CntRoller.setValue(att.GetLocation().y);
		y_CntRoller.setBroadcast(true);
		
		z_CntRoller.setBroadcast(false);
		z_CntRoller.setMin(0);
		z_CntRoller.setMax(2);
		z_CntRoller.setValue(att.m_nCurrentFloor);
		z_CntRoller.setNumberOfTickMarks(3);
		
		z_CntRoller.setBroadcast(true);
		
		sFocusedAttractionId = att.GetId();
		
		
//		x_CntRoller.remove();// .setMin((float)3);// setMin((float)3);
//		x_CntRoller = controlP5.addSlider("Attraction_X", att.m_Max_x,0, 0, 400, 250, 70, 10);
//		
//		x_CntRoller = controlP5.addSlider(att.GetId()+"_X", (float)(att.m_Min_x),((float)att.m_Max_x), att.GetLocation().x, x, y , 70, 10);
//		
//		y_CntRoller = controlP5.addSlider(att.GetId()+"_Y", (float)(att.m_Min_y),((float)att.m_Max_y), att.GetLocation().y, x,y , 70, 10);
//		
//		z_CntRoller = controlP5.addSlider(att.GetId()+"_Z", (int)(att.m_Min_z),((int)att.m_Max_z), att.GetLocation().z, x, y , 70, 10);
		

		
		x_CntRoller.setBroadcast(false);
		
		
		x_CntRoller.setMin((float)att.m_Min_x);
		x_CntRoller.setBroadcast(true);
//		x_CntRoller.setMax (att.m_Max_x);
		//x_CntRoller.setValue(att.GetLocation().x);
//		isActive_CntRoller.setValue(att.m_active);
		//isActive_CntRoller.setInternalValue(232);
		
	}
	
//	void SaveAttractionStateWrapper()
//	{
//		String sSelectedFile =selectFileImplPro("SaveStateFile","", FileDialog.SAVE);
//		if(sSelectedFile!= null)
//		{			
//			SaveAttractionState(sSelectedFile);
//			 delay(1000);
//		}
//		
//	}
	public void SaveAttractionState(String fileState)
	{
		
		try {
			 
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	 
			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("AttractionsSetting");
			doc.appendChild(rootElement);
			
			
			
			
			
			for(int i=0; i < alisDst.size(); i++)
			{

				Attraction att =  (Attraction) alisDst.get(i);
				Element staff = doc.createElement("Attractions");
				staff.setAttribute("Id", att.GetId());
				String sLocationAsString = att.GetLocation().x + "," +att.GetLocation().y + "," +att.GetLocation().z;
				staff.setAttribute("Location", sLocationAsString);
				staff.setAttribute("IsActive", att.m_active?"1":"0");
				staff.setAttribute("AttractionRange", Double.toString( att.AttractionRadious) );
				rootElement.appendChild(staff);
			}
			
	 
			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(fileState));
	 
			// Output to console for testing
			// StreamResult result = new StreamResult(System.out);
	 
			transformer.transform(source, result);
	 
			System.out.println("File saved!");
	 
		  } catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		  } catch (TransformerException tfe) {
			tfe.printStackTrace();
		  }
		}
	
//	public void LoadAttractionStateWrapper()
//	{
//		
//		//selectOutputPro("sds","asda");
//
//	}
	
	

		void fileSelected(File selection) {
		  if (selection == null) {
		    println("Window was closed or the user hit cancel.");
		  } else {
		    println("User selected " + selection.getAbsolutePath());
		  }
		}
	
	public void LoadAttractionState(String sFileName)
	{
		try
		{
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(new File(sFileName));
			
			doc.getDocumentElement().normalize();

			Element oElm = (Element) doc.getElementsByTagName(
					"AttractionsSetting").item(0);

			NodeList listOfAttraction = oElm.getElementsByTagName("Attractions");
			
			
			for (int s = 0; s < listOfAttraction.getLength(); s++) {
				Element examineAttractorInfo = (Element) listOfAttraction
						.item(s);

				String sId = examineAttractorInfo.getAttribute("Id");
				Attraction att = AttractionDictionary.get(sId);
				
				Vec3D newLocation = ParseVec3D(examineAttractorInfo.getAttribute("Location")); 
				
				
				att.SetLocationAndUpdateGUI(newLocation);
				//
				att.SetIsActiveAndUpdateGUI((examineAttractorInfo.getAttribute("IsActive").compareTo("1")  ==0 )) ;
				att.SetAttractionRadious(Double.parseDouble(examineAttractorInfo.getAttribute("AttractionRange")) );
				
//				Vec3D maxPos = ChangCeilingColor003
//						.ParseVec3D(examineAttractorInfo.getAttribute("Id"));
//				Vec3D minPos = ChangCeilingColor003
//						.ParseVec3D(examineAttractorInfo.getAttribute("MinPos"));
//
//				Vec3D intialePos = maxPos.add(minPos).scale(0.5f);
//
//				String ID = examineAttractorInfo.getAttribute("Id");
//				String description = examineAttractorInfo
//						.getAttribute("description");
//				int AttractionRadious = Integer.parseInt(examineAttractorInfo
//						.getAttribute("AttractionRadious"));
//
//				int minRadios = Integer.parseInt(examineAttractorInfo
//						.getAttribute("Min_R"));
//				int maxRadios = Integer.parseInt(examineAttractorInfo
//						.getAttribute("Max_R"));
//
//				Vec3D rgb = ChangCeilingColor003
//						.ParseVec3D(examineAttractorInfo
//								.getAttribute("RGBColor"));
//
//				Attraction examineAttractor = new Attraction(p5, ID,
//						description, (int) rgb.x, (int) rgb.y, (int) rgb.z,
//						AttractionRadious, minPos, maxPos, minRadios,
//						maxRadios, intialePos);
//
//				int nMaxConnection = Integer.parseInt(examineAttractorInfo
//						.getAttribute("MaxConnection"));
//
//				if (examineAttractorInfo.getAttribute("IsEntrance") != null) {
//					examineAttractor.m_bIsEntrance = Boolean
//							.parseBoolean(examineAttractorInfo
//									.getAttribute("IsEntrance"));
//				}
//
//				if (examineAttractorInfo.getAttribute("mass_radio") != "") {
//					int nMassRadios = Integer.parseInt(examineAttractorInfo
//							.getAttribute("mass_radio"));
//					examineAttractor.setMassRadios(nMassRadios);
//				}
//
//				if (examineAttractorInfo.getAttribute("IsExit") != null) {
//					examineAttractor.m_bIsExit = Boolean
//							.parseBoolean(examineAttractorInfo
//									.getAttribute("IsExit"));
//				}
//
//				if (examineAttractor.m_bIsEntrance
//						|| examineAttractor.m_bIsExit) {
//					p5.alisOrigin1.add(examineAttractor);
//					p5.alisOrigin.add(examineAttractor);
//				}
//
//				NodeList transformerSettings = examineAttractorInfo
//						.getElementsByTagName("Transformer");
//				if (transformerSettings.getLength() > 0) {
//					Element tranformationElm = (Element) transformerSettings
//							.item(0);
//					Vec3D transformationTarget = ChangCeilingColor003
//							.ParseVec3D(tranformationElm.getAttribute("To"));
//					examineAttractor.SetTransformation(transformationTarget);
//				}
//
//				examineAttractor.SetMaxNumberOfConnection(nMaxConnection);
//				NodeList attractorPriority = examineAttractorInfo
//						.getElementsByTagName("ConnectTo");
//
//				for (int i = 0; i < attractorPriority.getLength(); ++i) {
//					examineAttractor
//							.AddAttractorToPreferdList(((Element) attractorPriority
//									.item(i)).getAttribute("Id"));
//				}
//
//				p5.AttractionDictionary.put(ID, examineAttractor);
//				p5.alisDst.add(examineAttractor);
			}
			
			
		}
		catch (Exception e) {
			// TODO: handle exception
		}
	}	
	
	public int GetFloorFromHeight(float zValue)
	{
		return (int)(zValue/m_FloorHeight);
	}
	
	public String selectOutputPro(String prompt, String filestring) {
		  return selectFileImplPro(prompt, filestring, FileDialog.SAVE);
		}


		protected String selectFileImplPro(final String prompt, final String filestring, final int mode) {
		  this.checkParentFrame();

		  try {
		    javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
			public void run() {
			  FileDialog fileDialog =
			    new FileDialog(parentFrame, prompt, mode);
			  fileDialog.setFile(filestring);
			  fileDialog.setVisible(true);
			  String directory = fileDialog.getDirectory();
			  String filename = fileDialog.getFile();
			  selectedFile =
			    (filename == null) ? null : new File(directory, filename);
			}
		    }
		    );
		    return (selectedFile == null) ? null : selectedFile.getAbsolutePath();

		  } 
		  catch (Exception e) {
		    e.printStackTrace();
		    return null;
		  }
		} 

	
	
}
